import React, {useEffect, useState} from "react";
import styles from './index.module.scss';
import Logo from '@/assets/images/logo-spug-white.png';
import {Tabs, Tree, Input, Spin, Dropdown, Menu, Button, Drawer} from 'antd';
import {
  FolderOutlined,
  FolderOpenOutlined,
  CloudServerOutlined,
  SearchOutlined,
  SyncOutlined,
  CopyOutlined,
  ReloadOutlined,
  VerticalAlignBottomOutlined,
  VerticalAlignMiddleOutlined,
  CloseOutlined,
  LeftOutlined,
} from '@ant-design/icons';
import {apiGetHostGroupData} from "@/apis/ssh";
import AuthButton from "@/components/AuthButton";
import lodash from 'lodash';
import {hasPermission} from "@/common/permission";
import NotFound from "@/components/NotFound";
import Terminal from './Terminal'
import {randomString} from "@/common/utils";

const web_terminal =
  '                                                 __       __                          _                __\n' +
  '   _____ ____   __  __ ____ _   _      __ ___   / /_     / /_ ___   _____ ____ ___   (_)____   ____ _ / /\n' +
  '  / ___// __ \\ / / / // __ `/  | | /| / // _ \\ / __ \\   / __// _ \\ / ___// __ `__ \\ / // __ \\ / __ `// / \n' +
  ' (__  )/ /_/ // /_/ // /_/ /   | |/ |/ //  __// /_/ /  / /_ /  __// /   / / / / / // // / / // /_/ // /  \n' +
  '/____// .___/ \\__,_/ \\__, /    |__/|__/ \\___//_.___/   \\__/ \\___//_/   /_/ /_/ /_//_//_/ /_/ \\__,_//_/   \n' +
  '     /_/            /____/                                                                               \n'

const WebSSH: React.FC<any> = (props) => {

  const [title, setTitle] = useState('');
  const [searchValue, setSearchValue] = useState('');
  const [fetching, setFetching] = useState(true);
  const [treeData, setTreeData] = useState<any>([]);
  const [activeId, setActiveId] = useState<string>('');
  const [hosts, setHosts] = useState<any>([]);

  useEffect(() => {
    window.document.title = 'Spug web terminal'
    window.addEventListener('beforeunload', leaveTips)
    fetchNodes()
    return () => window.removeEventListener('beforeunload', leaveTips)
  }, [])

  function fetchNodes() {
    setFetching(true)
    apiGetHostGroupData().then(res => {
      setTreeData(res.data)
    }).finally(() => setFetching(false))
  }

  function leaveTips(e: any) {
    e.returnValue = '确定要离开页面？'
  }

  function renderIcon(node: any) {
    if (node.isLeaf) {
      return <CloudServerOutlined/>
    } else if (node.expanded) {
      return <FolderOpenOutlined/>
    } else {
      return <FolderOutlined/>
    }
  }

  function handleSelect(e: any) {
    // e.nativeEvent.detail > 1 是要双击才 openNode，单击不响应
    if (e.nativeEvent.detail > 1 && e.node.isLeaf) {
      _openNode(e.node)
    }
  }

  function _openNode(node: any, replace?: any) {
    const newNode = {...node}
    newNode.vId = randomString()

    if (replace) {
      const index = lodash.findIndex(hosts, {vId: node.vId})
      if (index >= 0) hosts[index] = newNode
    } else {
      hosts.push(newNode);
    }
    setHosts(lodash.cloneDeep(hosts))
    setActiveId(newNode.vId)
  }

  function handleOpenFileManager() {

  }

  function handleRemove(key: any, target: string) {
    const index = lodash.findIndex(hosts, (x: any) => x.vId === key);
    if (index === -1) return;
    switch (target) {
      case 'self':
        hosts.splice(index, 1)
        setHosts([...hosts])
        if (hosts.length > index) {
          setActiveId(hosts[index].vId)
        } else if (hosts.length) {
          setActiveId(hosts[index - 1].vId)
        } else {
          setActiveId('')
        }
        break
      case 'right':
        hosts.splice(index + 1, hosts.length)
        setHosts([...hosts])
        setActiveId(key)
        break
      case 'other':
        setHosts([hosts[index]])
        setActiveId(key)
        break
      case 'all':
        setHosts([])
        setActiveId('')
        break
      default:
        break
    }
  }

  function handeTabAction(action: string, host: any, e?: any) {
    if (e) e.stopPropagation()
    switch (action) {
      case 'copy':
        return _openNode(host)
      case 'reconnect':
        return _openNode(host, true)
      case 'rClose':
        return handleRemove(host.vId, 'right')
      case 'oClose':
        return handleRemove(host.vId, 'other')
      case 'aClose':
        return handleRemove(host.vId, 'all')
      default:
        break
    }
  }

  function TabRender(props: any) {
    const host = props.host;
    return (
      <Dropdown overlayStyle={{zIndex: 1000}} trigger={['contextMenu']} overlay={(
        <Menu onClick={({key, domEvent}) => handeTabAction(key, host, domEvent)}>
          <Menu.Item key="copy" icon={<CopyOutlined/>}>复制窗口</Menu.Item>
          <Menu.Item key="reconnect" icon={<ReloadOutlined/>}>重新连接</Menu.Item>
          <Menu.Item key="lClose" icon={<VerticalAlignBottomOutlined/>}>关闭左侧</Menu.Item>
          <Menu.Item key="rClose"
                     icon={<VerticalAlignBottomOutlined style={{transform: 'rotate(90deg)'}}/>}>关闭右侧</Menu.Item>
          <Menu.Item key="oClose"
                     icon={<VerticalAlignMiddleOutlined style={{transform: 'rotate(90deg)'}}/>}>关闭其他</Menu.Item>
          <Menu.Item key="aClose" icon={<CloseOutlined/>}>关闭所有</Menu.Item>
        </Menu>
      )}>
        <div className={styles.tabRender} onDoubleClick={() => handeTabAction('copy', host)}>{host.title}</div>
      </Dropdown>
    )
  }

  return (
    hasPermission('host.console.view|host.console.list') ? (
      <div className={styles.container}>
        <div className={styles.sider}>
          <div className={styles.logo}><img src={Logo} alt="logo"/></div>
          <div className={styles.hosts}>
            <Spin spinning={fetching}>
              <Input
                allowClear
                placeholder="输入检索"
                className={styles.search}
                prefix={<SearchOutlined style={{color: '#999'}}/>}
                onChange={e => setSearchValue(e.target.value)}
              />

              <Button icon={<SyncOutlined/>} type="link" loading={fetching} onClick={fetchNodes}/>

              {treeData.length > 0 ? (
                <Tree.DirectoryTree
                  defaultExpandAll={true}
                  expandAction="doubleClick"
                  treeData={treeData}
                  icon={renderIcon}
                  onSelect={(k, e) => handleSelect(e)}
                />) : null}
            </Spin>
          </div>
        </div>

        <div className={styles.content} style={{width: `calc(100% - 280px)`}}>
          <Tabs
            hideAdd
            activeKey={activeId}
            type="editable-card"
            onTabClick={key => setActiveId(key)}
            onEdit={(e, action) => action === 'remove' ? handleRemove(e, 'self') : null}
            style={{background: '#fff'}}
            tabBarExtraContent={hosts.length === 0 ?
              (<div className={styles.tips}>小提示：双击标签快速复制窗口，右击标签展开更多操作。</div>) :
              <AuthButton
                auth="host.console.list"
                type="link"
                disabled={!activeId}
                style={{marginRight: 5}}
                onClick={handleOpenFileManager}
                icon={<LeftOutlined/>}>文件管理器
              </AuthButton>
            }>
            {hosts.map((item: any) => (
              <Tabs.TabPane key={item.vId} tab={<TabRender host={item}/>}>
                {activeId === item.vId && <Terminal id={item.id} vId={item.vId} activeId={activeId}/>}
              </Tabs.TabPane>
            ))}
          </Tabs>
          {hosts.length === 0 && (<pre className={styles.fig}>{web_terminal}</pre>)}
        </div>

        {/*<Drawer
        title="文件管理器"
        placement="right"
        width={900}
        className={styles.drawerContainer}
        visible={visible}
        onClose={() => setVisible(false)}>
        <FileManager id={hostId}/>
      </Drawer>*/}
      </div>
    ) : (
      <div style={{height: '100vh'}}>
        <NotFound/>
      </div>
    )
  )
}

export default WebSSH
